﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using CSharpFilters;


namespace Loyalty.UI.Infrastructure
{
    public static class HtmlUtility
    {
        public static string RemoveHtmlTags(string text)
        {
            return string.IsNullOrEmpty(text)
                ? string.Empty
                : Regex.Replace(text, @"<(.|\n)*?>", string.Empty);
        }

        public static string HashingPassword(string Password)
        {
            return Crypto.HashPassword(Password);
        }

        public static string SetExplain(this string objectValue, int Count, string EndCharacter)
        {
            for (int i = 0; i < objectValue.Length; i++)
            {
                if ((i >= Count) && (objectValue[i] == ' '))
                {
                    return (objectValue.Substring(0, i) + EndCharacter);
                }
            }
            return objectValue;
        }

        public static string ImageUpload(HttpPostedFileBase StreamFile)
        {
            if (StreamFile == null)
                return null;
            WebImage webImage = new WebImage(StreamFile.InputStream);
            string FileName = StreamFile.FileName;
            int index = FileName.LastIndexOf('\\');
            FileName = FileName.Substring(index + 1);
            if (webImage == null)
                throw new Exception("هیچ فایلی وجود ندارد");

            while (System.IO.File.Exists(HttpContext.Current.Server.MapPath("~/Content/Upload/" + FileName)))
            {
                string extension = Path.GetExtension(FileName).ToLower();
                FileName = FileName.Substring(0, FileName.Length - extension.Length);
                FileName = FileName + "1" + extension;
            }
            string savingPath = HttpContext.Current.Server.MapPath("~/Content/Upload/" + FileName);

            webImage.Save(savingPath, null, false);
            return FileName;
        }

        public static string AvatarUpload(HttpPostedFileBase StreamFile, int Width, int Height)
        {
            // WebImage webImage = new WebImage(StreamFile.InputStream);
           
            string FileName = StreamFile.FileName;
            //if (webImage == null)
            //    throw new Exception("هیچ فایلی وجود ندارد");

            int index = FileName.LastIndexOf('\\');
            FileName = FileName.Substring(index + 1);
            string extension = Path.GetExtension(FileName).ToLower();
            FileName = FileName.Substring(0, FileName.Length - extension.Length);
            FileName = FileName + "1" + DateTime.Now.Second + extension;
            var image = System.Drawing.Image.FromStream(StreamFile.InputStream);
            System.Drawing.Image original = null;
            int width = image.Width;
            int height = image.Height;
            decimal num5 = Math.Round((decimal)((decimal)width / (decimal)height), 2);
            int num6 = width - Width;
            decimal num7 = Math.Round((decimal)((decimal)num6 / (decimal)num5), 2);
            int thumbHeight = height - ((int)num7);
            int thumbWidth = Width;
            original = ImageResize.Crop(image, Width, Height, ImageResize.AnchorPosition.Center);
            string savingPath = HttpContext.Current.Server.MapPath("~/Content/Images/Avatars/" + FileName + "");
            System.Drawing.Bitmap b = new System.Drawing.Bitmap(original);
            System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
            System.Drawing.Imaging.EncoderParameters param = new System.Drawing.Imaging.EncoderParameters(1);
            param.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
            b.Save(savingPath, info[1], param);
            image.Dispose();
            //webImage.Save(savingPath, null, false);
            return FileName;
        }

        public static string GetPropertyName<T, TKey>(Expression<Func<T, TKey>> expression)
        {
            var lambda = expression as LambdaExpression;
            MemberExpression memberExpression;
            if (lambda.Body is UnaryExpression)
            {
                var unaryExpression = lambda.Body as UnaryExpression;
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
            else
            {
                memberExpression = lambda.Body as MemberExpression;
            }
            if (memberExpression == null)
                throw new NullReferenceException("memberExpression");

            PropertyInfo propertyInfo = memberExpression.Member as PropertyInfo;
            //var err = this.CheckValidation();

            return propertyInfo.Name;
        }

        public static void SetPropertyValue<T, TKey>(T target, Expression<Func<T, TKey>> expression, object value)
        {
            var memberSelectorExpression = expression.Body as MemberExpression;
            if (memberSelectorExpression != null)
            {
                var property = memberSelectorExpression.Member as PropertyInfo;
                if (property != null)
                {
                    property.SetValue(target, Convert.ChangeType(value, typeof(string)));
                }
            }
        }

        public static object GetPropertyValue<T, TKey>(HtmlHelper<T> html, Expression<Func<T, TKey>> expression)
        {
            var lambda = expression as LambdaExpression;
            MemberExpression memberExpression;
            if (lambda.Body is UnaryExpression)
            {
                var unaryExpression = lambda.Body as UnaryExpression;
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
            else
            {
                memberExpression = lambda.Body as MemberExpression;
            }
            if (memberExpression == null)
                throw new NullReferenceException("memberExpression");

            PropertyInfo propertyInfo = memberExpression.Member as PropertyInfo;
            Func<T, TKey> method = expression.Compile();
            if (html.ViewData.Model == null)
                return null;
            TKey value = method(html.ViewData.Model);
            return value;
        }

        public static Int64 GetGUID(this string sender)
        {
            if (sender.Length > 20)
                sender = sender.Substring(12);
            Int64 ret = 0;
            for (int i = 0; i < sender.Length; i++)
            {
                ret = ret + Convert.ToInt32(sender[i]);
            }
            ret = ret * sender.Length;
            return ret;
        }

        public static string Serialize<T>(this T sender) where T : class
        {
            if (sender == null)
                return "";

            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(sender.GetType());
                serializer.WriteObject(ms, sender);
                ms.Position = 0;

                using (StreamReader reader = new StreamReader(ms))
                {
                    string ret = reader.ReadToEnd();
                    return ret;
                }
            }

        }

        public static T DeSerialize<T>(this string sender) where T : class
        {
            string s = sender;
            try
            {
                using (MemoryStream mstream = new MemoryStream(Encoding.Unicode.GetBytes(s)))
                {
                    DataContractJsonSerializer serializer =
                        new DataContractJsonSerializer(typeof(T));

                    return (T)serializer.ReadObject(mstream);
                }
            }
            catch
            {
                return null;
            }

        }

        private static IEnumerable<Type> GetSubClasses<T>()
        {
            return Assembly.GetCallingAssembly().GetTypes().Where(
                type => type.IsSubclassOf(typeof(T))).ToList();
        }

        public static List<string> GetControllerNames()
        {
            List<string> controllerNames = new List<string>();
            GetSubClasses<Controller>()
                .Where(
                    t =>
                        t.Namespace.Contains("RestaurantApp.Web.Areas.Backend.Controllers.Forms") &&
                        !t.Name.StartsWith("T4MVC"))
                .ToList()
                .ForEach(
                    type => controllerNames.Add(type.Name));
            return controllerNames;
        }

    }
}